Micron Document
🎖️GitЯра🎖️


Displaying Raw • Download

core/takserver/src/commonMain/kotlin/org/meshtastic/core/takserver/fountain/GenericCoTHandler.kt copilot/create-implementation-plan (228d872f) Text, 9.01 KB

T8b949e/*
* Copyright (c) 2026 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
Tff7b72package T7ee787org.meshtastic.core.takserver.fountain

Tff7b72import T7ee787co.touchlab.kermit.Logger
Tff7b72import T7ee787kotlinx.coroutines.delay
Tff7b72import T7ee787kotlinx.coroutines.sync.Mutex
Tff7b72import T7ee787kotlinx.coroutines.sync.withLock
Tff7b72import T7ee787okio.ByteString.Companion.toByteString
Tff7b72import T7ee787org.meshtastic.core.model.DataPacket
Tff7b72import T7ee787org.meshtastic.core.repository.CommandSender
Tff7b72import T7ee787org.meshtastic.core.takserver.CoTMessage
Tff7b72import T7ee787org.meshtastic.core.takserver.CoTXmlParser
Tff7b72import T7ee787org.meshtastic.core.takserver.TAKServerManager
Tff7b72import T7ee787org.meshtastic.core.takserver.toXml
Tff7b72import T7ee787org.meshtastic.proto.PortNum
Tff7b72import T7ee787kotlin.time.Clock

Tff7b72class T56d364GenericCoTHandlerTb4b4b4(Tff7b72private Tff7b72val Te6edf3commandSenderTb4b4b4: Te6edf3CommandSenderTb4b4b4, Tff7b72private Tff7b72val Te6edf3takServerManagerTb4b4b4: Te6edf3TAKServerManagerTb4b4b4) Tb4b4b4:
Te6edf3CoTHandler Tb4b4b4{
Tff7b72companion Tff7b72object Tb4b4b4{
Tff7b72private Tff7b72const Tff7b72val Te6edf3INTER_PACKET_DELAY_MS Tff7b72= T79c0ff1T79c0ff0T79c0ff0L
Tff7b72private Tff7b72const Tff7b72val Te6edf3ACK_RETRANSMIT_DELAY_MS Tff7b72= T79c0ff5T79c0ff0L
Tff7b72private Tff7b72const Tff7b72val Te6edf3PENDING_TRANSFER_TTL_MS Tff7b72= T79c0ff6T79c0ff0Te6edf3_000L
Tb4b4b4}

Tff7b72private Tff7b72val Te6edf3fountainCodec Tff7b72= Te6edf3FountainCodecTb4b4b4(Tb4b4b4)
Tff7b72private Tff7b72val Te6edf3pendingTransfersMutex Tff7b72= Te6edf3MutexTb4b4b4(Tb4b4b4)
Tff7b72private Tff7b72val Te6edf3pendingTransfers Tff7b72= Te6edf3mutableMapOfTff7b72<Tffa657IntTb4b4b4, Te6edf3PendingTransferTff7b72>Tb4b4b4(Tb4b4b4)

Tff7b72private Tff7b72data Tff7b72class T56d364PendingTransferTb4b4b4(
Tff7b72val Te6edf3transferIdTb4b4b4: Tffa657IntTb4b4b4,
Tff7b72val Te6edf3totalBlocksTb4b4b4: Tffa657IntTb4b4b4,
Tff7b72val Te6edf3dataHashTb4b4b4: Te6edf3ByteArrayTb4b4b4,
Tff7b72val Te6edf3startTimeTb4b4b4: Tffa657Long Tff7b72= Te6edf3ClockTb4b4b4.Te6edf3SystemTb4b4b4.Te6edf3nowTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toEpochMillisecondsTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4) Tb4b4b4{
Tff7b72override Tff7b72fun Td2a8ffequalsTb4b4b4(Te6edf3otherTb4b4b4: Tffa657Any?Tb4b4b4)Tb4b4b4: Tffa657Boolean Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72this Tff7b72=Tff7b72=Tff7b72= Te6edf3otherTb4b4b4) Tff7b72return Tff7b72true
Tff7b72if Tb4b4b4(Te6edf3other Tff7b72=Tff7b72= Tff7b72null Tff7b72|Tff7b72| Tff7b72thisTff7b72::Tff7b72class != T56d364otherTff7b72::Te6edf3classTb4b4b4) Tff7b72return Tff7b72false
Te6edf3other Tff7b72as Te6edf3PendingTransfer
Tff7b72return Te6edf3transferId Tff7b72=Tff7b72= Te6edf3otherTb4b4b4.Te6edf3transferId Tff7b72&Tff7b72&
Te6edf3totalBlocks Tff7b72=Tff7b72= Te6edf3otherTb4b4b4.Te6edf3totalBlocks Tff7b72&Tff7b72&
Te6edf3dataHashTb4b4b4.Te6edf3contentEqualsTb4b4b4(Te6edf3otherTb4b4b4.Te6edf3dataHashTb4b4b4) Tff7b72&Tff7b72&
Te6edf3startTime Tff7b72=Tff7b72= Te6edf3otherTb4b4b4.Te6edf3startTime
Tb4b4b4}

Tff7b72override Tff7b72fun Td2a8ffhashCodeTb4b4b4(Tb4b4b4)Tb4b4b4: Tffa657Int Tb4b4b4{
Tff7b72var Te6edf3result Tff7b72= Te6edf3transferId
Te6edf3result Tff7b72= T79c0ff3T79c0ff1 Tff7b72* Te6edf3result Tff7b72+ Te6edf3totalBlocks
Te6edf3result Tff7b72= T79c0ff3T79c0ff1 Tff7b72* Te6edf3result Tff7b72+ Te6edf3dataHashTb4b4b4.Te6edf3contentHashCodeTb4b4b4(Tb4b4b4)
Te6edf3result Tff7b72= T79c0ff3T79c0ff1 Tff7b72* Te6edf3result Tff7b72+ Te6edf3startTimeTb4b4b4.Te6edf3hashCodeTb4b4b4(Tb4b4b4)
Tff7b72return Te6edf3result
Tb4b4b4}
Tb4b4b4}

Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffsendGenericCoTTb4b4b4(Te6edf3cotMessageTb4b4b4: Te6edf3CoTMessageTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3xml Tff7b72= Te6edf3cotMessageTb4b4b4.Te6edf3toXmlTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3xmlBytes Tff7b72= Te6edf3xmlTb4b4b4.Te6edf3encodeToByteArrayTb4b4b4(Tb4b4b4)

Tff7b72val Te6edf3compressed Tff7b72= Te6edf3ZlibCodecTb4b4b4.Te6edf3compressTb4b4b4(Te6edf3xmlBytesTb4b4b4)
Tff7b72if Tb4b4b4(Te6edf3compressed Tff7b72=Tff7b72= Tff7b72nullTb4b4b4) Tb4b4b4{
Te6edf3LoggerTb4b4b4.Te6edf3w Tb4b4b4{ Ta5d6ff"Ta5d6ffFailed to compress CoT to ZlibTa5d6ff" Tb4b4b4}
Tff7b72return
Tb4b4b4}

Tff7b72val Te6edf3payload Tff7b72= Te6edf3ByteArrayTb4b4b4(Te6edf3compressedTb4b4b4.Te6edf3size Tff7b72+ T79c0ff1Tb4b4b4)
Te6edf3payloadTff7b72[T79c0ff0Tff7b72] Tff7b72= Te6edf3FountainConstantsTb4b4b4.Te6edf3TRANSFER_TYPE_COT
Te6edf3compressedTb4b4b4.Te6edf3copyIntoTb4b4b4(Te6edf3payloadTb4b4b4, T79c0ff1Tb4b4b4)

Te6edf3LoggerTb4b4b4.Te6edf3d Tb4b4b4{ Ta5d6ff"Ta5d6ffGeneric CoT: type=Tffd700${Te6edf3cotMessageTb4b4b4.Te6edf3typeTffd700}Ta5d6ff, xml=Tffd700${Te6edf3xmlBytesTb4b4b4.Te6edf3sizeTffd700}Ta5d6ffB, compressed=Tffd700${Te6edf3payloadTb4b4b4.Te6edf3sizeTffd700}Ta5d6ffBTa5d6ff" Tb4b4b4}

Tff7b72if Tb4b4b4(Te6edf3payloadTb4b4b4.Te6edf3size Tff7b72< Te6edf3FountainConstantsTb4b4b4.Te6edf3FOUNTAIN_THRESHOLDTb4b4b4) Tb4b4b4{
Te6edf3sendDirectTb4b4b4(Te6edf3payloadTb4b4b4)
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3sendFountainCodedTb4b4b4(Te6edf3payloadTb4b4b4)
Tb4b4b4}
Tb4b4b4}

Tff7b72private Tff7b72fun Td2a8ffsendDirectTb4b4b4(Te6edf3payloadTb4b4b4: Te6edf3ByteArrayTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3dataPacket Tff7b72=
Te6edf3DataPacketTb4b4b4(
Te6edf3to Tff7b72= Te6edf3DataPacketTb4b4b4.Te6edf3ID_BROADCASTTb4b4b4,
Te6edf3bytes Tff7b72= Te6edf3payloadTb4b4b4.Te6edf3toByteStringTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3dataType Tff7b72= Te6edf3PortNumTb4b4b4.Te6edf3ATAK_FORWARDERTb4b4b4.Te6edf3valueTb4b4b4,
Tb4b4b4)
Te6edf3commandSenderTb4b4b4.Te6edf3sendDataTb4b4b4(Te6edf3dataPacketTb4b4b4)
Te6edf3LoggerTb4b4b4.Te6edf3i Tb4b4b4{ Ta5d6ff"Ta5d6ffSent generic CoT directly: Tffd700${Te6edf3payloadTb4b4b4.Te6edf3sizeTffd700}Ta5d6ff bytes on port 257Ta5d6ff" Tb4b4b4}
Tb4b4b4}

Tff7b72private Tff7b72suspend Tff7b72fun Td2a8ffsendFountainCodedTb4b4b4(Te6edf3payloadTb4b4b4: Te6edf3ByteArrayTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3transferId Tff7b72= Te6edf3fountainCodecTb4b4b4.Te6edf3generateTransferIdTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3packets Tff7b72= Te6edf3fountainCodecTb4b4b4.Te6edf3encodeTb4b4b4(Te6edf3payloadTb4b4b4, Te6edf3transferIdTb4b4b4)
Tff7b72val Te6edf3hash Tff7b72= Te6edf3CryptoCodecTb4b4b4.Te6edf3sha256Prefix8Tb4b4b4(Te6edf3payloadTb4b4b4)

Te6edf3pendingTransfersMutexTb4b4b4.Te6edf3withLock Tb4b4b4{
Te6edf3pendingTransfersTff7b72[Te6edf3transferIdTff7b72] Tff7b72= Te6edf3PendingTransferTb4b4b4(Te6edf3transferIdTb4b4b4, Te6edf3packetsTb4b4b4.Te6edf3sizeTb4b4b4, Te6edf3hashTb4b4b4)
Tb4b4b4}

Te6edf3LoggerTb4b4b4.Te6edf3i Tb4b4b4{ Ta5d6ff"Ta5d6ffSending fountain-coded CoT: Tffd700${Te6edf3payloadTb4b4b4.Te6edf3sizeTffd700}Ta5d6ff bytes -> Tffd700${Te6edf3packetsTb4b4b4.Te6edf3sizeTffd700}Ta5d6ff blocks, xferId=Tffd700$Te6edf3transferIdTa5d6ff" Tb4b4b4}

Tff7b72for Tb4b4b4(Tb4b4b4(Te6edf3indexTb4b4b4, Te6edf3packetDataTb4b4b4) Tff7b72in Te6edf3packetsTb4b4b4.Te6edf3withIndexTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3dataPacket Tff7b72=
Te6edf3DataPacketTb4b4b4(
Te6edf3to Tff7b72= Te6edf3DataPacketTb4b4b4.Te6edf3ID_BROADCASTTb4b4b4,
Te6edf3bytes Tff7b72= Te6edf3packetDataTb4b4b4.Te6edf3toByteStringTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3dataType Tff7b72= Te6edf3PortNumTb4b4b4.Te6edf3ATAK_FORWARDERTb4b4b4.Te6edf3valueTb4b4b4,
Tb4b4b4)
Te6edf3commandSenderTb4b4b4.Te6edf3sendDataTb4b4b4(Te6edf3dataPacketTb4b4b4)

Tff7b72if Tb4b4b4(Te6edf3index Tff7b72< Te6edf3packetsTb4b4b4.Te6edf3size Tff7b72- T79c0ff1Tb4b4b4) Tb4b4b4{
Te6edf3delayTb4b4b4(Te6edf3INTER_PACKET_DELAY_MSTb4b4b4) T8b949e// Inter-packet delay
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}

Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffhandleIncomingForwarderPacketTb4b4b4(Te6edf3payloadTb4b4b4: Te6edf3ByteArrayTb4b4b4, Te6edf3senderNodeNumTb4b4b4: Tffa657IntTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3payloadTb4b4b4.Te6edf3isEmptyTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72return

Tff7b72if Tb4b4b4(Te6edf3fountainCodecTb4b4b4.Te6edf3isFountainPacketTb4b4b4(Te6edf3payloadTb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3payloadTb4b4b4.Te6edf3size Tff7b72=Tff7b72= Te6edf3FountainConstantsTb4b4b4.Te6edf3ACK_PACKET_SIZETb4b4b4) Tb4b4b4{
Te6edf3handleIncomingAckTb4b4b4(Te6edf3payloadTb4b4b4, Te6edf3senderNodeNumTb4b4b4)
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3handleFountainPacketTb4b4b4(Te6edf3payloadTb4b4b4, Te6edf3senderNodeNumTb4b4b4)
Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3handleDirectPacketTb4b4b4(Te6edf3payloadTb4b4b4, Te6edf3senderNodeNumTb4b4b4)
Tb4b4b4}
Tb4b4b4}

Tff7b72private Tff7b72fun Td2a8ffhandleDirectPacketTb4b4b4(Te6edf3payloadTb4b4b4: Te6edf3ByteArrayTb4b4b4, Te6edf3senderNodeNumTb4b4b4: Tffa657IntTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3payloadTb4b4b4.Te6edf3size Tff7b72<Tff7b72= T79c0ff1Tb4b4b4) Tff7b72return
Tff7b72val Te6edf3transferType Tff7b72= Te6edf3payloadTff7b72[T79c0ff0Tff7b72]
Tff7b72if Tb4b4b4(Te6edf3transferType Tff7b72!Tff7b72= Te6edf3FountainConstantsTb4b4b4.Te6edf3TRANSFER_TYPE_COTTb4b4b4) Tff7b72return

Tff7b72val Te6edf3exiData Tff7b72= Te6edf3payloadTb4b4b4.Te6edf3copyOfRangeTb4b4b4(T79c0ff1Tb4b4b4, Te6edf3payloadTb4b4b4.Te6edf3sizeTb4b4b4)
Te6edf3processDecompressedCoTTb4b4b4(Te6edf3exiDataTb4b4b4, Te6edf3senderNodeNumTb4b4b4)
Tb4b4b4}

Tff7b72private Tff7b72suspend Tff7b72fun Td2a8ffhandleFountainPacketTb4b4b4(Te6edf3payloadTb4b4b4: Te6edf3ByteArrayTb4b4b4, Te6edf3senderNodeNumTb4b4b4: Tffa657IntTb4b4b4) Tb4b4b4{
Te6edf3fountainCodecTb4b4b4.Te6edf3handleIncomingPacketTb4b4b4(Te6edf3payloadTb4b4b4)Tff7b72?.Te6edf3let Tb4b4b4{ Tb4b4b4(Te6edf3decodedDataTb4b4b4, Te6edf3transferIdTb4b4b4) Tff7b72-Tff7b72>
Tff7b72val Te6edf3hash Tff7b72= Te6edf3CryptoCodecTb4b4b4.Te6edf3sha256Prefix8Tb4b4b4(Te6edf3decodedDataTb4b4b4)
Te6edf3sendFountainAckTb4b4b4(Te6edf3transferIdTb4b4b4, Te6edf3hashTb4b4b4, Te6edf3senderNodeNumTb4b4b4)
Te6edf3delayTb4b4b4(Te6edf3ACK_RETRANSMIT_DELAY_MSTb4b4b4)
Te6edf3sendFountainAckTb4b4b4(Te6edf3transferIdTb4b4b4, Te6edf3hashTb4b4b4, Te6edf3senderNodeNumTb4b4b4)

Tff7b72if Tb4b4b4(Te6edf3decodedDataTb4b4b4.Te6edf3size Tff7b72> T79c0ff1 Tff7b72&Tff7b72& Te6edf3decodedDataTff7b72[T79c0ff0Tff7b72] Tff7b72=Tff7b72= Te6edf3FountainConstantsTb4b4b4.Te6edf3TRANSFER_TYPE_COTTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3exiData Tff7b72= Te6edf3decodedDataTb4b4b4.Te6edf3copyOfRangeTb4b4b4(T79c0ff1Tb4b4b4, Te6edf3decodedDataTb4b4b4.Te6edf3sizeTb4b4b4)
Te6edf3processDecompressedCoTTb4b4b4(Te6edf3exiDataTb4b4b4, Te6edf3senderNodeNumTb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}

Tff7b72private Tff7b72fun Td2a8ffprocessDecompressedCoTTb4b4b4(Te6edf3exiDataTb4b4b4: Te6edf3ByteArrayTb4b4b4, Te6edf3senderNodeNumTb4b4b4: Tffa657IntTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3xmlBytes Tff7b72= Te6edf3ZlibCodecTb4b4b4.Te6edf3decompressTb4b4b4(Te6edf3exiDataTb4b4b4) Tff7b72?: Tff7b72return
Tff7b72val Te6edf3xml Tff7b72= Te6edf3xmlBytesTb4b4b4.Te6edf3decodeToStringTb4b4b4(Tb4b4b4)

Tff7b72val Te6edf3result Tff7b72= Te6edf3CoTXmlParserTb4b4b4(Te6edf3xmlTb4b4b4)Tb4b4b4.Te6edf3parseTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3cot Tff7b72= Te6edf3resultTb4b4b4.Te6edf3getOrNullTb4b4b4(Tb4b4b4)

Tff7b72if Tb4b4b4(Te6edf3cot Tff7b72!Tff7b72= Tff7b72nullTb4b4b4) Tb4b4b4{
Te6edf3takServerManagerTb4b4b4.Te6edf3broadcastTb4b4b4(Te6edf3cotTb4b4b4)
Te6edf3LoggerTb4b4b4.Te6edf3i Tb4b4b4{ Ta5d6ff"Ta5d6ffReceived generic CoT from node Tffd700$Te6edf3senderNodeNumTa5d6ff: Tffd700${Te6edf3cotTb4b4b4.Te6edf3typeTffd700}Ta5d6ff" Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3LoggerTb4b4b4.Te6edf3wTb4b4b4(Te6edf3resultTb4b4b4.Te6edf3exceptionOrNullTb4b4b4(Tb4b4b4) Tff7b72?: Te6edf3ExceptionTb4b4b4(Ta5d6ff"Ta5d6ffUnknown parse errorTa5d6ff"Tb4b4b4)Tb4b4b4) Tb4b4b4{ Ta5d6ff"Ta5d6ffFailed to parse CoT XMLTa5d6ff" Tb4b4b4}
Tb4b4b4}
Tb4b4b4}

Tff7b72private Tff7b72fun Td2a8ffsendFountainAckTb4b4b4(Te6edf3transferIdTb4b4b4: Tffa657IntTb4b4b4, Te6edf3hashTb4b4b4: Te6edf3ByteArrayTb4b4b4, Te6edf3toNodeNumTb4b4b4: Tffa657IntTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3ackPacket Tff7b72=
Te6edf3fountainCodecTb4b4b4.Te6edf3buildAckTb4b4b4(
Te6edf3transferIdTb4b4b4,
Te6edf3FountainConstantsTb4b4b4.Te6edf3ACK_TYPE_COMPLETETb4b4b4,
Te6edf3received Tff7b72= T79c0ff0Tb4b4b4,
Te6edf3needed Tff7b72= T79c0ff0Tb4b4b4,
Te6edf3dataHash Tff7b72= Te6edf3hashTb4b4b4,
Tb4b4b4)

Tff7b72val Te6edf3dataPacket Tff7b72=
Te6edf3DataPacketTb4b4b4(
Te6edf3to Tff7b72= Te6edf3toNodeNumTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3bytes Tff7b72= Te6edf3ackPacketTb4b4b4.Te6edf3toByteStringTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3dataType Tff7b72= Te6edf3PortNumTb4b4b4.Te6edf3ATAK_FORWARDERTb4b4b4.Te6edf3valueTb4b4b4,
Tb4b4b4)
Te6edf3commandSenderTb4b4b4.Te6edf3sendDataTb4b4b4(Te6edf3dataPacketTb4b4b4)
Te6edf3LoggerTb4b4b4.Te6edf3d Tb4b4b4{ Ta5d6ff"Ta5d6ffSent fountain ACK for transfer Tffd700$Te6edf3transferIdTa5d6ff" Tb4b4b4}
Tb4b4b4}

Tff7b72private Tff7b72suspend Tff7b72fun Td2a8ffhandleIncomingAckTb4b4b4(Te6edf3payloadTb4b4b4: Te6edf3ByteArrayTb4b4b4, Te6edf3senderNodeNumTb4b4b4: Tffa657IntTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3ack Tff7b72= Te6edf3fountainCodecTb4b4b4.Te6edf3parseAckTb4b4b4(Te6edf3payloadTb4b4b4) Tff7b72?: Tff7b72return
Te6edf3LoggerTb4b4b4.Te6edf3d Tb4b4b4{ Ta5d6ff"Ta5d6ffReceived fountain ACK: xferId=Tffd700${Te6edf3ackTb4b4b4.Te6edf3transferIdTffd700}Ta5d6ff, type=Tffd700${Te6edf3ackTb4b4b4.Te6edf3typeTffd700}Ta5d6ff, from Tffd700$Te6edf3senderNodeNumTa5d6ff" Tb4b4b4}

Te6edf3pendingTransfersMutexTb4b4b4.Te6edf3withLock Tb4b4b4{
Te6edf3cleanupStalePendingTransfersLockedTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3pending Tff7b72= Te6edf3pendingTransfersTff7b72[Te6edf3ackTb4b4b4.Te6edf3transferIdTff7b72]
Tff7b72if Tb4b4b4(Te6edf3pending Tff7b72!Tff7b72= Tff7b72nullTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3ackTb4b4b4.Te6edf3type Tff7b72=Tff7b72= Te6edf3FountainConstantsTb4b4b4.Te6edf3ACK_TYPE_COMPLETETb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3ackTb4b4b4.Te6edf3dataHashTb4b4b4.Te6edf3contentEqualsTb4b4b4(Te6edf3pendingTb4b4b4.Te6edf3dataHashTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3LoggerTb4b4b4.Te6edf3i Tb4b4b4{ Ta5d6ff"Ta5d6ffFountain transfer Tffd700${Te6edf3ackTb4b4b4.Te6edf3transferIdTffd700}Ta5d6ff acknowledged by node Tffd700$Te6edf3senderNodeNumTa5d6ff" Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3LoggerTb4b4b4.Te6edf3w Tb4b4b4{ Ta5d6ff"Ta5d6ffFountain ACK hash mismatch for transfer Tffd700${Te6edf3ackTb4b4b4.Te6edf3transferIdTffd700}Ta5d6ff" Tb4b4b4}
Tb4b4b4}
Te6edf3pendingTransfersTb4b4b4.Te6edf3removeTb4b4b4(Te6edf3ackTb4b4b4.Te6edf3transferIdTb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}

T8b949e/** Must be called inside [pendingTransfersMutex]. */
Tff7b72private Tff7b72fun Td2a8ffcleanupStalePendingTransfersLockedTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3now Tff7b72= Te6edf3ClockTb4b4b4.Te6edf3SystemTb4b4b4.Te6edf3nowTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3toEpochMillisecondsTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3stale Tff7b72= Te6edf3pendingTransfersTb4b4b4.Te6edf3filter Tb4b4b4{ Tb4b4b4(Te6edf3_Tb4b4b4, Te6edf3vTb4b4b4) Tff7b72-Tff7b72> Te6edf3now Tff7b72- Te6edf3vTb4b4b4.Te6edf3startTime Tff7b72> Te6edf3PENDING_TRANSFER_TTL_MS Tb4b4b4}Tb4b4b4.Te6edf3keys
Te6edf3staleTb4b4b4.Te6edf3forEach Tb4b4b4{ Te6edf3id Tff7b72-Tff7b72>
Te6edf3pendingTransfersTb4b4b4.Te6edf3removeTb4b4b4(Te6edf3idTb4b4b4)
Te6edf3LoggerTb4b4b4.Te6edf3d Tb4b4b4{ Ta5d6ff"Ta5d6ffEvicted stale outbound pending transfer: Tffd700$Te6edf3idTa5d6ff" Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}

Served by rngit 1.5.2 - Generated in 0.08s